#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
处理器测试：验证 UnitSplitter 能正常分割并给出稳定结果。
不得使用断言，返回聚合结果。
"""

from typing import List, Dict

from processors.unit_splitter import UnitSplitter
from filters.filter_registry import FilterRegistry


def _case(name: str, passed: bool, details: str = "") -> Dict:
    return {"name": name, "passed": bool(passed), "details": details}


def _build_sample_pr() -> Dict:
    return {
        'pr_info': {'number': 123},
        'diffs': [
            {
                'file': 'src/app.py',
                'hunk_header': '@@ -1,3 +1,3 @@',
                'changes': [
                    {"type": "context", "content": "def foo():\n"},
                    {"type": "remove", "content": "    return 0\n"},
                    {"type": "add", "content": "    return 1\n"},
                    {"type": "context", "content": "\n"},
                ],
            },
            {
                'file': 'README.md',
                'hunk_header': '@@ -1,2 +1,2 @@',
                'changes': [
                    {"type": "context", "content": "# Title\n"},
                    {"type": "remove", "content": "Some text.\n"},
                    {"type": "add", "content": "Some docs updated.\n"},
                    {"type": "context", "content": "\n"},
                ],
            },
        ],
    }


def run_tests() -> List[Dict]:
    cases: List[Dict] = []

    # Build filters (all registered) to ensure integration path
    filters = [FilterRegistry.create(name) for name in FilterRegistry.list_available()]
    splitter = UnitSplitter(filter_rules=filters, enable_stats=True)

    pr = _build_sample_pr()

    try:
        valid, rejected = splitter.split_pr_into_units(pr)
        # Basic sanity: both lists are lists, and units include required keys when present
        v_ok = isinstance(valid, list) and all(isinstance(u, dict) for u in valid)
        r_ok = isinstance(rejected, list) and all(isinstance(u, dict) for u in rejected)
        cases.append(_case("splitter:types", v_ok and r_ok, details=f"valid={len(valid)} rejected={len(rejected)}"))

        # Stability: re-run and compare lengths and ids order (best-effort)
        valid2, rejected2 = splitter.split_pr_into_units(pr)
        stable = (len(valid) == len(valid2)) and (len(rejected) == len(rejected2))
        if stable and valid and valid2:
            stable = [u.get('unit_id') for u in valid] == [u.get('unit_id') for u in valid2]
        cases.append(_case("splitter:stability", bool(stable)))

        # Stats exposure should be a dict
        stats = splitter.get_filter_stats()
        stats_ok = isinstance(stats, dict)
        cases.append(_case("splitter:stats_dict", stats_ok))

        # Determine change type function sanity
        ct_ok = splitter.determine_change_type("x", "") in ("add", "modify", "delete", "unknown")
        cases.append(_case("splitter:change_type", ct_ok))

        # Extract change pairs works
        if pr['diffs']:
            pairs = splitter.extract_change_pairs(pr['diffs'][0]['changes'])
            pairs_ok = isinstance(pairs, list)
            cases.append(_case("splitter:extract_pairs", pairs_ok))
        else:
            cases.append(_case("splitter:extract_pairs", True, details="no diffs to test"))

    except Exception as e:
        cases.append(_case("splitter:exception", False, details=str(e)))

    return cases


